﻿using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;

namespace winS.UnityEditor.UIElement
{
    public class Toolbar : VisualElement
    {
        public static readonly float defaultHeight = 24f;
        public static readonly Color32 defaultLineColor = new Color32(40, 140, 255, 255);

        private static readonly List<TimeValue> durationList = new List<TimeValue>() { 0.2f, 0.2f, 0.2f };
        private static readonly List<StylePropertyName> propertyList = new List<StylePropertyName>() { "left", "width", "background-color" };
        private static readonly List<EasingFunction> easingFunctionList = new List<EasingFunction>() { EasingMode.EaseOutCirc, EasingMode.EaseOutCirc, EasingMode.EaseOutCirc };

        public event Action<int> onIndexChanged;

        public int currentSelectIndex { get; private set; }
        public float height { get => _height; set => SetHeight(value); }
        public Color lineColor { get => _lineColor; set => line.style.SetBackgroundColor(_lineColor = value); }

        private readonly List<ToolbarButton> toolbarButtonList = new List<ToolbarButton>();

        private Color _lineColor = defaultLineColor;

        private VisualElement line;
        private VisualElement buttonContainer;

        private int currentIndex;
        private float _height = defaultHeight;

        public new ToolbarButton this[int index] => toolbarButtonList[index];

        internal Toolbar()
        {
            CreateButtonContainer();
            CreateLine();
            RegisterCallback<GeometryChangedEvent>(OnGeometryChangedCallback);
        }
        internal Toolbar(float height) : this()
        {
            this.height = height;
        }

        public ToolbarButton CreateToolBarButton(string name, Action<int> callback)
        {
            return CreateToolBarButton(null, name, callback);
        }
        public ToolbarButton CreateToolBarButton(Texture texture, Action<int> callback)
        {
            return CreateToolBarButton(texture, null, callback);
        }
        public ToolbarButton CreateToolBarButton(Texture texture, string name, Action<int> callback)
        {
            if (currentIndex != 0) buttonContainer.Add(EditorElementUtility.elementFactory.CreateVerticalSplitline());
            ToolbarButton button = new ToolbarButton(currentIndex++);
            button.lineColor = _lineColor;
            button.onClick += index =>
            {
                callback?.Invoke(index);
                currentSelectIndex = index;
                onIndexChanged?.Invoke(index);
                line.style.left = toolbarButtonList[index].layout.x;
                line.style.width = toolbarButtonList[index].layout.width;
                line.style.SetBackgroundColor(button.lineColor);
            };
            button.SetLabel(name);
            if (texture != null) button.SetTexture(texture);
            button.style.minHeight = height;
            toolbarButtonList.Add(button);
            buttonContainer.Add(button);
            return button;
        }

        private void SetHeight(float newHeight)
        {
            _height = newHeight;
            foreach (var button in toolbarButtonList) button.style.minHeight = newHeight;
        }
        private void CreateButtonContainer()
        {
            Add(buttonContainer = EditorElementUtility.elementFactory.CreateRow());
        }
        private void CreateLine()
        {
            Add(line = EditorElementUtility.elementFactory.CreateEditorElement());
            line.style.bottom = 0f;
            line.style.minHeight = 1f;
            line.style.position = Position.Absolute;
            line.style.transitionProperty = propertyList;
            line.style.transitionDuration = durationList;
            line.style.transitionTimingFunction = easingFunctionList;
            line.style.SetBackgroundColor(lineColor);
        }
        private void OnGeometryChangedCallback(GeometryChangedEvent geometryChangedEvent)
        {
            if (toolbarButtonList.Count == 0) return;
            line.style.transitionProperty = null;
            line.style.transitionDuration = null;
            line.style.width = toolbarButtonList[currentSelectIndex].layout.width;
            line.style.left = toolbarButtonList[currentSelectIndex].layout.x;
            line.style.transitionProperty = propertyList;
            line.style.transitionDuration = durationList;
        }
    }
}